package com.zztl.infiniteBand.ui.view

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.animation.LinearInterpolator
import com.zztl.infiniteBand.R
import com.zztl.infiniteBand.util.UiUtils


class ProgressWaveView(mContext: Context, attrs: AttributeSet) : View(mContext, attrs) {

    private var mWidth=0
    private var mHeight=0
    //View的画笔
    private var wavePaint: Paint? = null
    private var textPaint: Paint? = null
    private var circlePaint: Paint? = null

    //波浪的路径
    private var path: Path? = null
    //sin曲线的长度：一个周期的长度
    private val cycle = 160
    //每次平移的长度，为四分之一个周期
    private val translateX = cycle / 4
    //sin曲线振幅的高度
    private val waveHeight = 80
    //sin曲线的起点坐标
    private var startPoint: Point? = null
    //当前波浪的进度
    private var progress = 0
    //当前波浪的速度
    private val waveSpeech = 150
    //是否启用了自动增长进度
    private var isAutoIncrease = false
    private var mWaveColor: Int = 0
    private var mBgColor: Int = 0
    private var mTextColor: Int = 0
    private var mTextSize: Float = 0.toFloat()

    init {
        initAttrs(mContext, attrs)
        initPaint()
    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
         context.obtainStyledAttributes(attrs, R.styleable.ProgressWaveView).apply {
             mWaveColor =getColor(R.styleable.ProgressWaveView_dw_wave_color, context.resources.getColor(R.color.color_007aff))
             mBgColor =getColor(R.styleable.ProgressWaveView_dw_wave_color, context.resources.getColor(R.color.color_F7F6F8))
             mTextColor = getColor(R.styleable.ProgressWaveView_dw_txt_color, context.resources.getColor(R.color.color_1B1100))
             mTextSize = getDimension(R.styleable.ProgressWaveView_dw_txt_size, UiUtils.dip2px(context, 35).toFloat())
             recycle()
         }

    }


    private fun initPaint() {
        path = Path()

        wavePaint = Paint().apply {
            isAntiAlias = true
            style = Paint.Style.FILL
            color = mWaveColor
        }


        circlePaint = Paint().apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            color = mBgColor
        }


        textPaint = Paint().apply {
            isAntiAlias = true
            textSize = mTextSize
            color = mTextColor
        }

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //设置内间距
        //        setPadding(20, 20, 20, 20);
        //裁剪画布为圆形
        clipCicle(canvas)
        //绘制圆形
        drawCircle(canvas)
        //绘制波浪区域
        drawWavePath(canvas)
        //绘制进度文字
        drawProcessText(canvas)

        //自动增长进度
        if (isAutoIncrease) {
            if (progress >= 100) {
                progress = 0
            } else {
                progress++
            }
            //更新UI
            postInvalidateDelayed(waveSpeech.toLong())
        }
    }

    /**
     * 绘制进度文字
     *
     * @param canvas
     */
    private fun drawProcessText(canvas: Canvas) {
        //画布的大小
        val targetRect = Rect(0, 0, width, height)
        val fontMetrics = textPaint!!.fontMetricsInt
        val baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2
        // 下面这行是实现水平居中，drawText对应改为传入targetRect.centerX()
        textPaint!!.textAlign = Paint.Align.CENTER
        canvas.drawText(progress.toString() + "%", targetRect.centerX().toFloat(), baseline.toFloat(), textPaint!!)
    }

    /**
     * 绘制波浪区域
     *
     * @param canvas
     */
    private fun drawWavePath(canvas: Canvas) {
        if (progress == 100) {
            canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), (width / 2).toFloat(), wavePaint!!)
        } else {
            //根据进度改变起点坐标的y值
            startPoint!!.y = ((1 - progress / 100.0) * (height / 2 + width / 2)).toInt()
            Log.e("TAG", "startPoint.y:" + startPoint!!.y)
            //移动区域起点
            path!!.moveTo(startPoint!!.x.toFloat(), startPoint!!.y.toFloat())
            var j = 1
            //循环绘制正弦曲线区域，循环两个周期
            for (i in 1..8) {
                if (i % 2 == 0) {
                    //波峰
                    path!!.quadTo((startPoint!!.x + cycle * j).toFloat(), (startPoint!!.y + waveHeight).toFloat(),
                            (startPoint!!.x + cycle * 2 * i).toFloat(), startPoint!!.y.toFloat())
                } else {
                    //波谷
                    path!!.quadTo((startPoint!!.x + cycle * j).toFloat(), (startPoint!!.y - waveHeight).toFloat(),
                            (startPoint!!.x + cycle * 2 * i).toFloat(), startPoint!!.y.toFloat())
                }
                j += 2
            }
            //绘制封闭的区域
            path!!.lineTo(width.toFloat(), height.toFloat())//右下角
            path!!.lineTo(startPoint!!.x.toFloat(), height.toFloat())//左下角
            path!!.lineTo(startPoint!!.x.toFloat(), startPoint!!.y.toFloat())//起点
            path!!.close()
            //绘制区域
            canvas.drawPath(path!!, wavePaint!!)
            path!!.reset()
            //一开始的起点是在-160，160 = 40 + 40 + 40 + 40，走完一个周期则回到原点
            if (startPoint!!.x + translateX >= 0) {
                startPoint!!.x = -cycle * 4
            } else {
                startPoint!!.x += translateX
            }
        }
    }

    /**
     * 绘制圆形
     *
     * @param canvas
     */
    private fun drawCircle(canvas: Canvas) {
        canvas.drawPaint(circlePaint!!)
        canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), (width / 2).toFloat(), circlePaint!!)
    }

    /**
     * 裁剪画布为圆形
     *
     * @param canvas
     */
    private fun clipCicle(canvas: Canvas) {
        val circlePath = Path()
        circlePath.addCircle((width / 2).toFloat(), (height / 2).toFloat(), (width / 2).toFloat(), Path.Direction.CW)
        canvas.clipPath(circlePath)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        //由于是一个圆形，所以取的值是宽高的最小值
        mWidth = measureSize(400, widthMeasureSpec)
        mHeight = measureSize(400, heightMeasureSpec)
        mWidth = Math.min(mWidth, mHeight)
        mHeight = Math.min(mWidth, mHeight)
        setMeasuredDimension(mWidth, mHeight)
        //初始化起点，为屏幕外的一个周期
        startPoint = Point(-cycle * 4, 0)
    }

    /**
     * 测量宽高
     *
     * @param defaultSize
     * @param measureSpec
     * @return
     */
    private fun measureSize(defaultSize: Int, measureSpec: Int): Int {
        var result = defaultSize
        val mode = View.MeasureSpec.getMode(measureSpec)
        val size = View.MeasureSpec.getSize(measureSpec)
        when (mode) {
            View.MeasureSpec.UNSPECIFIED //如果没有指定大小，就设置为默认大小
            -> result = defaultSize
            View.MeasureSpec.AT_MOST, View.MeasureSpec.EXACTLY -> result = size
        }
        return result
    }


    /**
     * 开启自动增长
     */
    fun startIncrease() {
        isAutoIncrease = true
        invalidate()
    }

    /**
     * 设置当前进度
     *
     * @param progress 进度
     */
    fun setProgress(progress: Int) {
        if (progress > 100 || progress < 0)
            return

        this.progress = progress
        invalidate()
    }

    /**
     * 通过动画设置当前进度
     *
     * @param targetProcess 进度 <=100
     * @param duration      动画时长
     */
    fun setProgress(targetProcess: Int, duration: Int) {
        if (progress > 100 || progress < 0)
            return

        val progressAnimator = ValueAnimator.ofInt(progress, targetProcess)
        progressAnimator.duration = duration.toLong()
        progressAnimator.setTarget(progress)
        progressAnimator.interpolator = LinearInterpolator()
        progressAnimator.addUpdateListener { animation -> setProgress(animation.animatedValue as Int) }
        progressAnimator.start()
    }

    /**
     * 获取当前进度
     *
     * @return
     */
    fun getProgress(): Int {
        return progress
    }
}
